package by.pavlyukevich.paymentsystem.panel;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.datetime.markup.html.basic.DateLabel;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.springframework.orm.jpa.JpaSystemException;

import by.pavlyukevich.paymentsystem.add.AbstractDataProvider;
import by.pavlyukevich.paymentsystem.add.ErrorEvent;
import by.pavlyukevich.paymentsystem.add.PanelUpdateEvent;
import by.pavlyukevich.paymentsystem.dataaccess.filter.Filter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.TransactionFilter;
import by.pavlyukevich.paymentsystem.datamodel.Transaction;
import by.pavlyukevich.paymentsystem.datamodel.Transaction_;
import by.pavlyukevich.paymentsystem.panel.card.CardEditPanel;
import by.pavlyukevich.paymentsystem.services.TransactionService;

public class TransactionListPanel extends Panel {
	@Inject
	private TransactionService transactionService;
	private TransactionFilter transactionFilter;
	private Panel respPanel;

	public TransactionListPanel(String id) {
		this(id, new TransactionFilter());
	}

	public TransactionListPanel(String id, TransactionFilter transactionFilter) {
		super(id);
		this.transactionFilter = transactionFilter;
		this.respPanel = this;
	}

	@Override
	protected void onInitialize() {
		super.onInitialize();
		setOutputMarkupId(true);

		TransactionDataProvider transactionDP = new TransactionDataProvider(Transaction_.date,
				transactionFilter);

		final WebMarkupContainer transactionTable = new WebMarkupContainer("transaction-table");
		transactionTable.setOutputMarkupId(true);
		add(transactionTable);

		DataView<Transaction> dataView = new DataView<Transaction>("transaction-row",
				transactionDP, 20) {

			@Override
			protected void populateItem(Item<Transaction> item) {

				final Transaction transaction = item.getModelObject();

				item.add(DateLabel.forDatePattern("date", "dd.MM.yyyy"));
				item.add(new AjaxLink<Void>("senderAccount") {

					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new AccountEditPanel("ac-panel", transaction.getSenderAccount(),
										respPanel)));

					}
				}.setBody(new Model<String>(Long.toString(transaction.getSenderAccount()
						.getAccountNumber()))));

				item.add(new AjaxLink<Void>("payeeAccount") {

					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new AccountEditPanel("ac-panel", transaction.getPayeeAccount(),
										respPanel)));

					}
				}.setBody(new Model<String>(Long.toString(transaction.getPayeeAccount()
						.getAccountNumber()))));

				AjaxLink<Void> cardLink = new AjaxLink<Void>("senderCard") {

					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new CardEditPanel("ac-panel", transaction.getSenderCard(),
										respPanel)));

					}
				};
				cardLink.setBody(new Model<String>((transaction.getSenderCard() != null) ? Long
						.toString(transaction.getSenderCard().getCardNumber()) : ""));
				item.add(cardLink);

				item.add(new Label("amount"));

				item.add(new AjaxLink<Void>("delete") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						try {
							transactionService.delete(transaction);
							target.add(respPanel);
						} catch (JpaSystemException e) {
							error(new ResourceModel("t.error.unableToDelete").getObject());
							send(getPage(), Broadcast.BREADTH, new ErrorEvent(target));
						}

					}
				});

				item.add(new AjaxLink<Void>("edit") {
					@Override
					public void onClick(AjaxRequestTarget target) {
						send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
								new TransactionEditPanel("ac-panel", transaction, respPanel)));
					}
				});
			}

		};

		transactionTable.add(dataView);
		add(new AjaxLink<Void>("new") {

			@Override
			public void onClick(AjaxRequestTarget target) {
				send(getPage(), Broadcast.BREADTH, new PanelUpdateEvent(target,
						new TransactionEditPanel("ac-panel", new Transaction(), respPanel)));
			}
		});

		add(new MyPagingNavigator("paging", dataView));

		add(new OrderByBorder<SingularAttribute<Transaction, ?>>("sortByDate", Transaction_.date,
				transactionDP));
		add(new OrderByBorder<SingularAttribute<Transaction, ?>>("sortBySenderAccount",
				Transaction_.senderAccount, transactionDP));
		add(new OrderByBorder<SingularAttribute<Transaction, ?>>("sortBySenderCard",
				Transaction_.senderCard, transactionDP));
		add(new OrderByBorder<SingularAttribute<Transaction, ?>>("sortByPayeeAccount",
				Transaction_.payeeAccount, transactionDP));

	}

	private class TransactionDataProvider extends AbstractDataProvider<Transaction> {
		public TransactionDataProvider(SingularAttribute<Transaction, ?> sortParam,
				Filter<Transaction> filter) {
			super(sortParam, filter, transactionService);
		}
	};

}
